package com.ryzx.jpa.helper.comment;

import org.hibernate.boot.Metadata;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;

//public class CommentIntegrator{}
@Component
public class CommentIntegrator implements Integrator {
    public static final CommentIntegrator INSTANCE = new CommentIntegrator();

    public CommentIntegrator() {
        super();
    }
    @Override
    public void integrate(Metadata metadata, BootstrapContext bootstrapContext, SessionFactoryImplementor sessionFactory) {
        processComment(metadata);
    }

    @Override
    public void disintegrate(SessionFactoryImplementor sessionFactoryImplementor, SessionFactoryServiceRegistry sessionFactoryServiceRegistry) {
    }

    private void processComment(Metadata metadata) {
        for (PersistentClass persistentClass : metadata.getEntityBindings()) {
            Class<?> clz = persistentClass.getMappedClass();
            if (clz.isAnnotationPresent(Comment.class)) {
                Comment comment = clz.getAnnotation(Comment.class);
                persistentClass.getTable().setComment(comment.value());
            }
            Property identifierProperty = persistentClass.getIdentifierProperty();
            if (identifierProperty != null) {
                fieldComment(persistentClass, identifierProperty.getName());
            } else {
                org.hibernate.mapping.Component component = persistentClass.getIdentifierMapper();
                if (component != null) {
                    for (Property property : component.getProperties()) {
                        fieldComment(persistentClass, property.getName());
                    }
                }
            }
            for (Property property : persistentClass.getProperties()) {
                fieldComment(persistentClass, property.getName());
            }
        }
    }

    private void fieldComment(PersistentClass persistentClass, String columnName) {
        try {
            Field field = persistentClass.getMappedClass().getDeclaredField(columnName);
            if (field.isAnnotationPresent(Comment.class)) {
                String comment = field.getAnnotation(Comment.class).value();
                String sqlColumnName = persistentClass.getProperty(columnName).getValue().getColumns().get(0).getText();
                for (org.hibernate.mapping.Column column : persistentClass.getTable().getColumns()) {
                    if (sqlColumnName.equalsIgnoreCase(column.getName())) {
                        column.setComment(comment);
                        break;
                    }
                }
            }
        } catch (NoSuchFieldException | SecurityException ignored) {
        }
    }
}